SeoprofesionalFetchers = function() {

var FETCHER_NOBARS = 1;
var FetcherBase = function() {}
FetcherBase.prototype.init = function(name, shortname, id, color, color_array) {
  this.enabled = 1;
  this.flags = 0;
  this.nicename = this.name = name;
  this.shortname = shortname;
  this.id = id;
  this.refresh = 0;
  this.coherent = 0;
  this.color = color;
  this.color_array = color_array;
  this.prefered = false;
};
FetcherBase.prototype.get_name = function() {
  return this.name;
};
FetcherBase.prototype.get_max = function(vals)    {
  throw Exception("fetch must be implemented in the subclass");
};
FetcherBase.prototype.fetch = function(callback, uri)  {
  throw Exception("fetch must be implemented in the subclass");
};
FetcherBase.prototype.updateUri = function(uri) {
    // if the fetcher actually fetches ranks for different than supplied
    // uri, this function returns the updated uri
    return uri;
};
FetcherBase.prototype.onreadystatechange = function(req, evt, callback, uri) {
  if (4==req.readyState) {
    if(200==req.status) {
      var rank = this.parseResponse(req.responseText);
      if (callback) {
        callback(this, uri, rank);
      }
    }
  }
};
SRankFetcher = function() {};
SRankFetcher.prototype = new FetcherBase();
SRankFetcher.prototype.super_init = FetcherBase.prototype.init;
SRankFetcher.prototype.init = function() {
  this.super_init("srank", "S", 2, "#F00", [0xff,0,0,0xff]);
};
SRankFetcher.prototype.get_max = function(vals)    {  return 10;  };
SRankFetcher.prototype.fetch = function(callback, uri)  {
  uri = SeoprofesionalTools.cleanHttpsURL(uri);
  var that = this;
  var req = new XMLHttpRequest();
  req.onreadystatechange = function(evt) {
    that.onreadystatechange(req, evt, callback, uri);
  };
  var body = '<?xml version="1.0" encoding="UTF-8"?>' +
      '<methodCall>' +
    '<methodName>getRank</methodName>' +
    '<params>' +
        '<param>' +
      '<value>' +
          '<string>0</string>' +
      '</value>' +
        '</param>' +
        '<param>' +
      '<value>' +
          '<string>' + uri + '</string>' +
      '</value>' +
        '</param>' +
        '<param>' +
      '<value>' +
          '<i4>0</i4>' +
      '</value>' +
        '</param>' +
    '</params>' +
      '</methodCall>';  
  req.open("POST", "http://srank.seznam.cz/RPC2");
  req.setRequestHeader("Content-Type", "text/xml");
//  req.setRequestHeader("Host", "srank.seznam.cz");
//  req.setRequestHeader("Connection", "Close");
  req.send(body);
};
SRankFetcher.prototype.parseResponse = function(text) {
  var rank = null;
  var r = /<name>rank<\/name>\s*<value><i[a-z0-9]*>([^<]*)<\/i/gi;
  var m = r.exec(text);
  if (null!=m) {
      rank = Math.floor(10*m[1]/255);
      m = r.exec();
      while (null!=m) {
    m = r.exec();
      }
  }
  return rank;
};
PageRankFetcher = function() {};
PageRankFetcher.prototype = new FetcherBase();
PageRankFetcher.prototype.super_init = FetcherBase.prototype.init;
PageRankFetcher.prototype.init = function() {
  this.super_init("pagerank", "G", 3, "#0F0", [ 0, 0xff, 0, 0xff]);
    this.prefered = true;

};
PageRankFetcher.prototype.get_max = function(vals)  {  return 10;  };
PageRankFetcher.prototype.get_pr_url = function(url_in) {
  //from: http://www.7is7.com/software/bookmarklets/googlepagerank.html
  var zF = function(a,b) {
    var z=parseInt(80000000,16);
    if(z&a){ a=a>>1;a&=~z;a|=0x40000000;a=a>>(b-1);
    }else{ a=a>>b; }
    return(a);
  },
  mix=function(a,b,c){
    a-=b;a-=c;a^=(zF(c,13));b-=c;b-=a;b^=(a<<8);c-=a;c-=b;c^=(zF(b,13));
    a-=b;a-=c;a^=(zF(c,12));b-=c;b-=a;b^=(a<<16);c-=a;c-=b;c^=(zF(b,5));
    a-=b;a-=c;a^=(zF(c,3));b-=c;b-=a;b^=(a<<10);c-=a;c-=b;c^=(zF(b,15));
    return(new Array((a),(b),(c)));
  },
  GoogleCH=function(url,length){
    if(arguments.length==1)length=url.length;
    var a=0x9E3779B9,b=0x9E3779B9,c=0xE6359A60,k=0,len=length,mx=new Array();
    while(len>=12){
      a+=(url[k+0]+(url[k+1]<<8)+(url[k+2]<<16)+(url[k+3]<<24));
      b+=(url[k+4]+(url[k+5]<<8)+(url[k+6]<<16)+(url[k+7]<<24));
      c+=(url[k+8]+(url[k+9]<<8)+(url[k+10]<<16)+(url[k+11]<<24));
      mx=mix(a,b,c);a=mx[0];b=mx[1];c=mx[2];k+=12;len-=12;
    }
    c+=length;
    switch(len){
    case 11:c+=url[k+10]<<24;
    case 10:c+=url[k+9]<<16;
    case 9:c+=url[k+8]<<8;
    case 8:b+=(url[k+7]<<24);
    case 7:b+=(url[k+6]<<16);
    case 6:b+=(url[k+5]<<8);
    case 5:b+=(url[k+4]);
    case 4:a+=(url[k+3]<<24);
    case 3:a+=(url[k+2]<<16);
    case 2:a+=(url[k+1]<<8);
    case 1:a+=(url[k+0]);
    }
    mx=mix(a,b,c);
    if(mx[2]<0)return(0x100000000+mx[2]);
    else{ return(mx[2]); }
  },
  strord=function(string){
    var result=new Array();
    for(i=0;i<string.length;i++){
      result[i]=string[i].charCodeAt(0);
    }
    return(result);
  };
  return 'http://www.google.com/search?client=navclient-auto&ch=6'+GoogleCH(strord('info:'+url_in))+'&features=Rank&q=info:'+encodeURIComponent(url_in);
};
PageRankFetcher.prototype.fetch = function(callback, uri) {
  uri = SeoprofesionalTools.cleanHttpsURL(uri);
  var req = new XMLHttpRequest();
  var that = this;
  req.onreadystatechange = function(evt) {
    that.onreadystatechange(req, evt, callback, uri);
  };
  req.open("GET", this.get_pr_url(uri));
  //req.setRequestHeader("Connection", "Close");
  //req.setRequestHeader("User-Agent", "Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.8.0.6) Gecko/20060728 Firefox/1.5");
  req.send(null);
};
PageRankFetcher.prototype.parseResponse = function(text) {
  var rank = null;
  if (0==text.indexOf("Rank_") && text.lastIndexOf(':')!=-1) {
    rank = parseInt(text.substring(text.lastIndexOf(':')+1));
  }
  return rank;
};

YLinksFetcher = function() {};
YLinksFetcher.prototype = new FetcherBase();
YLinksFetcher.prototype.super_init = FetcherBase.prototype.init;
YLinksFetcher.prototype.init = function() {
  this.super_init("ylinks", "Y", 4, "#0524e1", [ 0x05, 0x24, 0xe1, 0xff]);
  this.coherent = 1;
  this.flags = FETCHER_NOBARS;
};
YLinksFetcher.prototype.get_max = function(vals) {
  if (null==vals) {
    return 100;
  }
  try {
    var m = 5;
    for (var i = 0;i<vals.length;i++) {
      if (vals[i][1]>m)
        m = vals[i][1];
    }
    return m;
  } catch (e) {}
  return 100;
};
YLinksFetcher.prototype.fetch = function(callback, uri) {
  uri = SeoprofesionalTools.cleanHttpsURL(uri);
  var req = new XMLHttpRequest();
  var that = this;
  req.onreadystatechange = function(evt) {
    that.onreadystatechange(req, evt, callback, uri);
  };
  req.open("GET", "http://siteexplorer.search.yahoo.com/search?bwm=i&bwmf=u&bwms=p&fr=siteexplorer&fr2=seo-rd-se&p=" + escape(uri))
  req.send(null);
};
YLinksFetcher.prototype.parseResponse = function(text) {
  var rank = null;
  var r = /Inlinks\s+\(([0-9,\.]+)\)/gi;
  var m = r.exec(text);
  if (null!=m) {
      var s = m[1].replace(/[\.,]/g, "")
      rank = 1*s;
      m = r.exec();
      while (null!=m) {
        m = r.exec();
      }
  }
  return rank;
};

SeznamIndexedFetcher = function() {};
SeznamIndexedFetcher.prototype = new FetcherBase();
SeznamIndexedFetcher.prototype.super_init = FetcherBase.prototype.init;
SeznamIndexedFetcher.prototype.init = function() {
  this.super_init("sidx", "SX", 5, "#dd0099", [ 0xdd, 0x00, 0x99, 0xff]);
  this.coherent = 1;
  this.flags = FETCHER_NOBARS;
};
SeznamIndexedFetcher.prototype.get_max = function(vals) {
  if (null==vals) {
    return 100;
  }
  try {
    var m = 5;
    for (var i = 0;i<vals.length;i++) {
      if (vals[i][1]>m)
        m = vals[i][1]*1.2;
    }
    return m;
  } catch (e) {}
  return 100;
};
SeznamIndexedFetcher.prototype.fetch = function(callback, uri) {
  if (uri!=SeoprofesionalTools.getHttpDomain(uri)) {
    return;
  }
  uri = SeoprofesionalTools.cleanHttpsURL(uri);
  uri = this.updateUri(uri);
  var req = new XMLHttpRequest();
  var that = this;
  req.onreadystatechange = function(evt) {
    that.onreadystatechange(req, evt, callback, uri);
  };
  req.open("GET", "http://search.seznam.cz/?mod=f&q=site:" + escape(uri));
  req.send(null);
};
SeznamIndexedFetcher.prototype.parseResponse = function(text) {
  var rank = null;
  var r = /zobrazujeme[^z]*z([0-9 ]+)nalezen/gi;
  var m = r.exec(text);
  if (null!=m) {
      var s = m[1].replace(/\s/g, "")
      rank = 1*s;
      m = r.exec();
      while (null!=m) {
        m = r.exec();
      }
  }
  return rank;
};

GoogleIndexedFetcher = function() {};
GoogleIndexedFetcher.prototype = new FetcherBase();
GoogleIndexedFetcher.prototype.super_init = FetcherBase.prototype.init;
GoogleIndexedFetcher.prototype.init = function() {
  this.super_init("gidx", "GX", 6, "#00dd99", [ 0x00, 0xdd, 0x99, 0xff]);
  this.coherent = 1;
  this.flags = FETCHER_NOBARS;
};
GoogleIndexedFetcher.prototype.get_max = function(vals) {
  if (null==vals) {
    return 100;
  }
  try {
    var m = 5;
    for (var i = 0;i<vals.length;i++) {
      if (vals[i][1]>m)
        m = vals[i][1]*1.1;
    }
    return m;
  } catch (e) {}
  return 100;
};
GoogleIndexedFetcher.prototype.fetch = function(callback, uri) {
  if (uri!=SeoprofesionalTools.getHttpDomain(uri)) {
    return;
  }
  uri = SeoprofesionalTools.cleanHttpsURL(uri);
  var req = new XMLHttpRequest();
  var that = this;
  req.onreadystatechange = function(evt) {
    that.onreadystatechange(req, evt, callback, uri);
  };
  req.open("GET", "http://www.google.com/search?hl=en&q=site:" + escape(uri));
  req.send(null);
};
GoogleIndexedFetcher.prototype.parseResponse = function(text) {
  var rank = null;
  var r = /resultStats"?>About\s+([0-9\s,\.]+)results/gi;
  var m = r.exec(text);
  if (null!=m) {
      var s = m[1].replace(/[\s,\.]/g, "")
      rank = 1*s;
      m = r.exec();
      while (null!=m) {
        m = r.exec();
      }
  }
  return rank;
};

var fetchers = [ new SRankFetcher(), new PageRankFetcher(), new YLinksFetcher(), new SeznamIndexedFetcher(), new GoogleIndexedFetcher() ];
for (var i = 0;i<fetchers.length;i++) {
  fetchers[i].init();
  fetchers[i].nicename = chrome.i18n.getMessage(fetchers[i].name);
  if (!fetchers[i].nicename) {
    fetchers[i].nicename = fetchers[i].name;
  }
  fetchers[i].enabled = prefsGetBool(fetchers[i].name, true);
  fetchers[i].refresh = prefsGetInt(fetchers[i].name + ".refresh", 0);
  fetchers[i].prefered = prefsGetBool(fetchers[i].name + ".prefered", fetchers[i].prefered);
}

this.storageListener = function(evt) {
  if (0!=evt.key.indexOf("options.")) return;
  var opt = evt.key.substr(8);
  var sub = opt.indexOf(".");
  if (-1!=sub) {
    var l = sub;
    sub = opt.substr(l+1);
    opt = opt.substr(0, l);
  } else {
    sub = "";
  }
  for (var i = 0;i<fetchers.length;i++) {
    if (opt==fetchers[i].name) {
      fetchers[i].enabled = prefsGetBool(fetchers[i].name, true);
      fetchers[i].prefered = prefsGetBool(fetchers[i].name + ".prefered", fetchers[i].prefered);
      fetchers[i].refresh = prefsGetInt(fetchers[i].name + ".refresh", 0);
      return ;
    }
  }
}

try {
    window.addEventListener("storage", this.storageListener, false);
} catch(e) {
    console.log("EXCEPTION: Could not hook storage event listener.", e);
}

return fetchers;
}();

